﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using System.Web;

namespace Hangout.Web.Core.Meetup
{
    public class Meetup
    {

        public static Model.Hangouts InsertHangout(int userId,bool moderateHangoutRequest,string description, string text, Model.Location screenshotLocation, Model.Location location,DateTime hangoutDateTime, DateTime clientdatetime,ref Model.HangoutDBEntities context)
        {

            Model.Hangouts lastHangout = GetLastHangout(userId, ref context);

            if (lastHangout != null)
            {
                if (lastHangout.StatusText == text)
                {
                    return lastHangout;
                }
            }

            

            Model.Hangouts obj = new Model.Hangouts();
            obj.DateTimeStamp = DateTime.Now;
            if (description != null)
            {
                obj.Description = description;
            }
            if (screenshotLocation.ClientDateTimeStamp != null)
            {
                obj.ScreenshotLocationID = Core.Location.UserLocation.UpdateUserLocation(screenshotLocation, ref context).LocationID;
                
            }
            obj.ModerateHangoutRequests = moderateHangoutRequest;
            obj.StatusText = text;
            
            if (location.ClientDateTimeStamp != null)
            {
                obj.LocationID=Core.Location.UserLocation.InsertLocation(location, ref context).LocationID;
            }

            obj.HangoutDateTime = hangoutDateTime;
            obj.ClientDateTimeStamp = clientdatetime;
            obj.UserID = userId;
            

            context.Hangouts1.AddObject(obj);

            context.SaveChanges();

            return obj;
            
        }

        

        public static Model.Hangouts GetLastHangout(int userid, ref Model.HangoutDBEntities context)
        {
            return context.Hangouts1.Where(o => o.UserID == userid).ToList().LastOrDefault();
        }

        

        public static Model.Hangouts GetHangout(int hangoutId, ref Model.HangoutDBEntities context)
        {
            return context.Hangouts1.Where(o => o.HangoutID == hangoutId).FirstOrDefault();
        }

        public static List<Model.UserProfile> GetUsersInHangout(int hangoutId, ref Model.HangoutDBEntities context)
        {
            return context.UserHangouts.Where(o => o.HangoutID == hangoutId && (o.HangoutRequestAccepted == true||o.HangoutRequestAccepted==null)).Select(o=>o.User).Select(o=>o.UserProfile).ToList();
        }


        public static List<HangoutCommentData> GetHangoutComments(int hangoutId, ref Model.HangoutDBEntities context)
        {
            return context.HangoutComments.Where(o => o.HangoutID == hangoutId).ToList().Select(o => new HangoutCommentData() { comment = o, profile = o.User.UserProfile }).ToList();
            
            
        }

        public static List<HangoutCommentData> GetHangoutCommentsAfter(int hangoutId,DateTime after, ref Model.HangoutDBEntities context)
        {
            return context.HangoutComments.Where(o => o.HangoutID == hangoutId&&o.DateTimeStamp>after).ToList().Select(o => new HangoutCommentData() { comment = o, profile = o.User.UserProfile }).ToList();


        }

        public static void AddHangoutComment(int userId, int hangoutId, string text,DateTime clientdatetime ,ref Model.HangoutDBEntities context)
        {
            Model.HangoutComment comment = new Model.HangoutComment();
            comment.UserID = userId;
            comment.HangoutID = hangoutId;
            comment.DateTimeStamp = DateTime.Now;
            comment.ClientDateTimeStamp = clientdatetime;
            comment.CommentText = text;

            context.AddToHangoutComments(comment);
            context.SaveChanges();

        }

        public static bool IsPinned(int userId, int hangoutId, Model.HangoutDBEntities context)
        {
            if (context.HangoutPinneds.Where(o => o.UserID == userId && o.HangoutID == hangoutId).Count()==0)
            {
                return false;
            }

            return true;
        }

        public static List<HangoutData> GetAllPinned(int userId,ref Model.HangoutDBEntities context)
        {
            return context.HangoutPinneds.Where(o => o.UserID == userId).ToList().Select(o => new HangoutData() { Hangout = o.Hangout, Profile=o.User.UserProfile,Pinned=true }).ToList();
        }

        public static void PinHangout(int userid, int hangoutId,ref Model.HangoutDBEntities context)
        {
            if (context.HangoutPinneds.Where(o=>o.UserID==userid&&o.HangoutID==hangoutId).Count()==0)
            {
                Model.HangoutPinned pin = new Model.HangoutPinned();
                pin.UserID = userid;
                pin.HangoutID = hangoutId;
                context.AddToHangoutPinneds(pin);
                context.SaveChanges();

            }
        }

        public static void UnPinHangout(int userid, int hangoutId, ref Model.HangoutDBEntities context)
        {
            if (IsPinned(userid, hangoutId, context))
            {

                List<Model.HangoutPinned> pin = context.HangoutPinneds.Where(o => o.UserID == userid && o.HangoutID == hangoutId).ToList();
                if (pin.Count > 0)
                {

                    foreach (Model.HangoutPinned p in pin)
                    {
                        context.HangoutPinneds.DeleteObject(p);
                    }
                }
                context.SaveChanges();

            }
        }

        public static bool JoinedInHangout(int userId, int hangoutId, ref Model.HangoutDBEntities context)
        {
            if (context.UserHangouts.Where(o => o.UserID == userId && o.HangoutID == hangoutId && (o.HangoutRequestAccepted == true || o.HangoutRequestAccepted == null)).FirstOrDefault() == null)
            {
                return false;
            }

            return true;
        }

        public static CheckInStatus CheckIn(int userId, int hangoutId,double latitude,double longitude, DateTime clientDateTime, ref Model.HangoutDBEntities context)
        {
            Model.Hangouts hangout = GetHangout(hangoutId, ref context);
            if (hangout == null)
            {
                return CheckInStatus.HangoutNotFound;
            }
            if(JoinedInHangout(userId,hangoutId,ref context))
            {
                if (!IsCheckedIn(userId, hangoutId, ref context))
                {
                    double dis = Core.Location.Distance.CalculateDistance(latitude, longitude, hangout.Location.Latitude, hangout.Location.Longitude);

                    if (hangout.HangoutDateTime.Value.AddHours(2) < clientDateTime)
                    {
                        //time passed
                        return CheckInStatus.HangoutTimePassed;
                    }

                    if (clientDateTime.AddHours(4) < hangout.HangoutDateTime.Value)
                    {
                        //time passed
                        return CheckInStatus.EarlyCheckin;
                    }
                    
                    if (dis > 2)
                    {
                        return CheckInStatus.NotAtHangoutLocation;
                    }

                    Model.HangoutCheckIn check = new Model.HangoutCheckIn();
                    check.ClientDateTimeStamp = clientDateTime;
                    check.DateTimeStamp = DateTime.Now;
                    check.HangoutID = hangoutId;
                    check.UserID = userId;
                    context.HangoutCheckIns.AddObject(check);
                    context.SaveChanges();

                    return CheckInStatus.Success;
                }
                else
                {
                    return CheckInStatus.AlreadyCheckedIn;
                }
            }
            else
            {
                return CheckInStatus.NotJoinedInHangout;
            }

            return CheckInStatus.Error;

        }

        public static bool IsCheckedIn(int userId, int hangoutId, ref Model.HangoutDBEntities context)
        {
            if (context.HangoutCheckIns.Where(o=>o.UserID==userId&&o.HangoutID==hangoutId).FirstOrDefault()==null)
            {
                return false;
            }

            return true;
        }

        public static void JoinHangout(int userId, int hangoutId,DateTime clientDateTime, ref Model.HangoutDBEntities context)
        {
            if (!JoinedInHangout(userId, hangoutId, ref context))
            {
                Model.UserHangout hangout = new Model.UserHangout();
                hangout.DateTimeStamp = DateTime.Now;
                hangout.HangoutID = hangoutId;
                hangout.Text = "";
                hangout.UserID = userId;
               
                context.AddToUserHangouts(hangout);
                context.SaveChanges();

                
            }
        }

        public static void UnJoinHangout(int userId, int hangoutId,DateTime clientdatetime, ref Model.HangoutDBEntities context)
        {
            if (JoinedInHangout(userId, hangoutId, ref context))
            {
                context.UserHangouts.DeleteObject(context.UserHangouts.Where(o => o.UserID == userId && o.HangoutID == hangoutId && (o.HangoutRequestAccepted == true || o.HangoutRequestAccepted == null)).FirstOrDefault());
                context.SaveChanges();
                AddHangoutComment(userId, hangoutId, "Left this hangout", clientdatetime, ref context);
            }
        }

        public static bool CanCheckIn(int userid, int hangoutid, ref Model.HangoutDBEntities context)
        {
            if (JoinedInHangout(userid, hangoutid, ref context))
            {
                if (!IsCheckedIn(userid, hangoutid, ref context))
                {
                    return true;
                }
            }

            return false;
        }

        public static List<HangoutData> GetUserHangout(int userId, int take, int skip, Model.HangoutDBEntities context)
        {
            return (from a in context.UserHangouts
                    where a.UserID==userId
                    orderby a.DateTimeStamp descending
                    select a).Skip(skip).Take(take).ToList().Select(o => new HangoutData() { Hangout = o.Hangout, Profile = o.User.UserProfile, Pinned = IsPinned(o.UserID, o.HangoutID, context) }).ToList();
        }

        public static List<HangoutData> GetLatestHangouts(int userid, int take, int skip, Model.HangoutDBEntities context)
        {

            Model.Location location = Core.Location.UserLocation.GetLastLocation(userid, ref context);

            if (location == null)
            {
                return new List<HangoutData>();
            }

            if (String.IsNullOrEmpty(location.Locality))
            {
                return new List<HangoutData>();
            }

            List<Model.Hangouts> hangouts= context.Hangouts1.Where(o =>o.Location1.Locality==location.Locality||o.UserID==userid).OrderByDescending(o=>o.DateTimeStamp).Skip(skip).Take(take).ToList();
            List<HangoutData> data = new List<HangoutData>();
            foreach (Model.Hangouts hangout in hangouts)
            {
                data.Add(new HangoutData() { Hangout = hangout, Profile = Core.Accounts.User.GetUserProfile(hangout.UserID,context), Pinned = IsPinned(hangout.UserID, hangout.HangoutID, context) });
            }

            return data;
            
        }

        public static int GetNoOfCheckIns(int userId, Model.HangoutDBEntities context)
        {
            return context.HangoutCheckIns.Where(o => o.UserID == userId).Count();
        }

        public static int GetMaxNoOfPeopleInUserCheckins(int userid, Model.HangoutDBEntities context)
        {
           return context.HangoutCheckIns.Where(o => o.UserID == userid).Select(o => o.Hangout).Select(o => o.HangoutCheckIns.Count).OrderByDescending(o => o).ToList().FirstOrDefault();
        }

        public static bool HangoutAtMidnight(int userid, Model.HangoutDBEntities context)
        {
            if (context.HangoutCheckIns.Where(o => o.UserID == userid && EntityFunctions.DiffHours(o.ClientDateTimeStamp.TimeOfDay,new TimeSpan(0,0,0))<=3).Count() > 0)
            {
                return true;
            }

            return false;
        }

        public static List<Model.Hangouts> GetUserLatestHangouts(int userId, int skip, int take, ref Model.HangoutDBEntities context)
        {
            return context.Hangouts1.Where(o => o.UserID == userId).OrderByDescending(o => o.DateTimeStamp).Skip(skip).Take(take).ToList();
        }

        public static List<HangoutData> SearchHangouts(int userid, string text,int take,int skip, Model.HangoutDBEntities context)
        {
            
            List<int> userIds = Core.Compatibility.Compatibility.GetCompatibleUsers(userid, context);
            userIds.Add(userid); //add your own user id to the list 
            List<Model.Hangouts> hangouts = context.Hangouts1.Where(o => userIds.Contains(o.UserID)&&o.StatusText.Contains(text)).OrderByDescending(o => o.DateTimeStamp).Skip(skip).Take(take).ToList();
            List<HangoutData> data = new List<HangoutData>();
            foreach (Model.Hangouts hangout in hangouts)
            {
                data.Add(new HangoutData() { Hangout = hangout, Profile = Core.Accounts.User.GetUserProfile(hangout.UserID, context), Pinned = IsPinned(hangout.UserID, hangout.HangoutID, context) });
            }

            return data;
        }

        
        

        


        
    }
}